import CryptoJS from 'crypto-js'
import AesUtil from './aes.js'
import SignatureGenerate from "./signatureGenerate";

class JiaMi{

	constructor(option){
		this.option = option;//
		this.encOption = {
			mode: CryptoJS.mode.ECB,
			padding: CryptoJS.pad.NoPadding,
			iv: ''
		};
	}

  /**
   * 定义加密函数
   * @param {string} data - 需要加密的数据, 传过来前先进行 JSON.stringify(data);
   * @param {string} key - 加密使用的 key
   */
  aesEncrypt = (data) => {
	const key = CryptoJS.enc.Utf8.parse(this.option.initKey);
	/**
	 * CipherOption, 加密的一些选项:
	 *   mode: 加密模式, 可取值(CBC, CFB, CTR, CTRGladman, OFB, ECB), 都在 CryptoJS.mode 对象下
	 *   padding: 填充方式, 可取值(Pkcs7, AnsiX923, Iso10126, Iso97971, ZeroPadding, NoPadding), 都在 CryptoJS.pad 对象下
	 *   iv: 偏移量, mode === ECB 时, 不需要 iv
	 * 返回的是一个加密对象
	 */
	const cipher = CryptoJS.AES.encrypt(data, key, this.encOption);
	// 将加密后的数据转换成 Base64
	const base64Cipher = cipher.ciphertext.toString(CryptoJS.enc.Base64);
	// const resultCipher = base64Cipher.replace(/\+/g,'-').replace(/\//g,'_');
	// 返回加密后的经过处理的 Base64
	return base64Cipher;
}

  /**
   * 定义解密函数
   * @param {string} encrypted - 加密的数据;
   * @param {string} key - 加密使用的 key
   */
    aesDecrypt = (encrypted) => {
		const key = CryptoJS.enc.Utf8.parse(this.option.initKey);
		// // 先将 Base64 还原一下, 因为加密的时候做了一些字符的替换
		// const restoreBase64 = encrypted.replace(/\-/g,'+').replace(/_/g,'/');
		// 这里 mode, padding, iv 一定要跟加密的时候完全一样
		// 返回的是一个解密后的对象
		const decipher = CryptoJS.AES.decrypt(encrypted, key, this.encOption);
		// 将解密对象转换成 UTF8 的字符串
		const resultDecipher = CryptoJS.enc.Utf8.stringify(decipher);
		// 返回解密结果
		return resultDecipher;
    }

	parseUrl = (url,key) => {
		var idx = url.indexOf('?');
		if(~url.indexOf('nextStep')){
			idx = url.indexOf('&');
		}
		var newUrl;
		if(idx == -1){
			newUrl = url;
		}else{
			newUrl = url.substr(0,idx+1);
			var param = url.substr(idx+1).split('&');
			for(var i = 0 ;i < param.length; i++){
  				param[i] = this.dealParam(param[i],key);
			}
			newUrl += param.join('&');

			var isAndroid = 'ios';//android or ios
			if((/android/gi).test(navigator.appVersion)){
				isAndroid = 'android';
			}
		}
		return newUrl;
	}
	dealParam = (val)=>{
		var idx = val.indexOf('=');
		var retVal = val.substr(0,idx+1);
		var pVal = val.substr(idx+1);
		if(pVal == undefined || pVal == 'undefined'){
			pVal = '';
		} else {
			pVal = this.aesEncrypt(pVal);
		}
		return retVal + pVal;
    }

	iEncrpt = (oldUrl)=>{
		return this.parseUrl(oldUrl);
	};

	iEncrptParam=(val)=>{
		if(val == undefined || val == 'undefined'){
			return '';
		} else {
			return this.aesEncrypt(val+'');
		}
	}
	//解密
	decrptParam = (val)=>{
		return this.aesDecrypt(val+'');
	}
    decrptCloudAIParam = (val, secretKey)=>{
        return AesUtil.decrypt(val + '', secretKey)
    }
	iEncrptParamMap = (map)=>{
		let value,retData={};
		for(let key in map){
			value = this.iEncrptParam(map[key]);
			retData[key] = value;
		}
		return retData;
	}
	//对map中的key排序
	keyCompare = (map)=>{
		let retStr = '';
		let keyArr = [];
		for(let key in map){
			keyArr.push(key);
		}
		keyArr.sort();//对key进行升序
		for(let i = 0; i < keyArr.length; i++){
			let key = keyArr[i];
			if(map[key] == undefined || map[key] == 'undefined'){
				retStr += key;
			} else {
				retStr += key + map[key];
			}
		}
		return retStr;
	}
	digitGetSign = (url)=>{
		var idx = url.indexOf('?');
		var retMap = {};
		if(idx == -1){
			return retMap;
		}else{
			var param = url.substr(idx+1).split('&');
			for(var i = 0 ;i < param.length; i++){
				let idxInner = param[i].indexOf('=');
				let retVal = param[i].substr(0,idxInner);
				let pVal = param[i].substr(idxInner+1);
				retMap[retVal] = pVal;
			}
		}
		return this.keyCompare(retMap);
	}
	digitPostSign = (map)=>{
		return keyCompare(map);
	}
	digitSign = (salt5G,param,method,contentType)=>{
		let secrest = CryptoJS.SHA256('pancnl123').toString();
		if(salt5G){
			secrest = CryptoJS.SHA256(salt5G).toString();
		}
		secrest = secrest.toUpperCase();
		let reqParam = '';
		if(method == 'get'){
			reqParam = this.digitGetSign(param);//get方式的url进行签名
			// console.info(reqParam);
		} else {
			if(contentType && ~contentType.indexOf('multipart/form-data')){
				reqParam = this.digitPostSign({});
			} else {
				reqParam = this.digitPostSign(param);
			}
		}
		// console.info(reqParam +'***,***'+ secrest);
		let retSign = CryptoJS.SHA256(reqParam + secrest).toString();
		// console.info(retSign);
		return retSign && retSign.toUpperCase();
	}

    digitCloudAISign = (resData)=>{

        let retSign = SignatureGenerate.generateDecMD5(resData)
        return retSign
    }

	digitAldSign = (resData)=>{

		let retSign = CryptoJS.SHA256(resData).toString();
		return retSign && retSign.toUpperCase();
	}
	parseUrlNew = (url, secretKey) =>{
		let idx = url.indexOf('?');
		let newUrl = url;
		if(idx != -1){
			//获取？前面的字符串
			newUrl = url.substr(0,idx + 1);
			let param = url.substr(idx + 1);//取？后面的参数
			param = this.delUndefinedParam(param);//清除链接里的所有undefined
			let wgtEncryParam = AesUtil.encrypt(param, secretKey);
			newUrl += 'wgtEncryParam=' + this.translateParam(wgtEncryParam);//转译 + & /等特殊字符
		}
		return newUrl;
	}
	//清除undefined
	delUndefinedParam = (p)=>{
		let reg = /undefined/g;
		let param = p;
		if(typeof param === 'string'){
			param = param.replace(reg, "");
		}
		return param;
	}
	//参数转译
	translateParam = (p)=>{
		let param = p;
		if(typeof param === 'string'){
			param = param.replace(/\+/g,'%2B').replace(/&/g,'%26').replace(/\//g,'%2F').replace(/=/g,'%3D')
			//空格处理
			// param = param.replace(/\s/g,'%20');
		}
		return param;

	};
	//参数整体加解密处理
	aesEncryptAllParams = (data, secretKey)=>{
		let beforeStr = data;//加密前的变量
		let returVal = '';//加密后的值
		if(typeof data === 'string'){//get方法的url参数
			// console.info('get方法加密前：:',beforeStr);
			returVal = this.parseUrlNew(data, secretKey);

		} else if(typeof data === 'object'){//post类型的对象参数
			try{
				beforeStr = JSON.stringify(data);
				beforeStr = this.delUndefinedParam(beforeStr);//清undefined参数值
			} catch(e){
				beforeStr = '';
				console.info(beforeStr+'===转json字符串异常')
			}
			returVal = AesUtil.encrypt(beforeStr, secretKey);
			//加密后对特殊字符进行转译
			returVal = this.translateParam(returVal);
			// console.info(returVal);
		} else {
			beforeStr = '';
		}

		return returVal;
	}
}
export default JiaMi;


